#pragma once
#include <vector>
#include "Worker.h"
#include "Service.h"
#include "SocketWorker.h"
#include <unordered_map>
#include "Conn.h"

class Sunnet{
    public:
        static Sunnet * inst;
        //服务列表
        unordered_map<uint32_t, shared_ptr<Service>> services;
        //最大ID
        uint32_t maxId = 0;
        //读写锁
        pthread_rwlock_t servicesLock;
    public:
        Sunnet();
        void Start();
        void Wait();
        //增删服务
        uint32_t NewService(shared_ptr<string> type);
        //获取服务
        shared_ptr<Service> GetService(uint32_t id);
        //仅服务自己调用
        void KillService(uint32_t id);

    //网络连接操作接口//////////////////////////////////////////////////////////////
    public:
        int Listen(uint32_t port, uint32_t serviceId);
        void CloseConn(uint32_t fd);
        //对外Event接口
        void ModifyEvent(int fd, bool epollOut);

    //工作线程//////////////////////////////////////////////////////////////
    private:
        int WORKER_NUM = 3;
        vector<Worker*> workers;
        vector<thread*> workerThreads;
    private:
        void StartWorker();

    //Sokcet线程//////////////////////////////////////////////////////////////
    private:
        SocketWorker* socketWorker;
        thread* socketThread;
    private:
        //开启Socket线程
        void StartSocket();

    //休眠和唤醒//////////////////////////////////////////////////////////////
    private:
        pthread_mutex_t sleepMtx;
        pthread_cond_t sleepCond;
        int sleepCount = 0;     //休眠工作线程数
    public:
        //唤醒工作线程
        void CheckAndWeakUp();
        //让工作线程等待(仅工作线程调用)
        void WorkerWait();

    //全局队列//////////////////////////////////////////////////////////////
    private:
        queue<shared_ptr<Service>> globalQueue;
        int globalLen = 0;  //队列长度
        pthread_spinlock_t globalLock;  //锁
    public:
        //发送消息
        void Send(uint32_t told, shared_ptr<BaseMsg> msg);
        //全局队列操作
        shared_ptr<Service> PopGlobalQueue();
        void PushGlobalQueue(shared_ptr<Service> srv);
    
    //连接管理//////////////////////////////////////////////////////////////
    private:
        unordered_map<uint32_t, shared_ptr<Conn>> conns;
        pthread_rwlock_t connsLock; //读写锁

    public:
        //增删查Conn
        int AddConn(int fd, uint32_t id, Conn::TYPE type);
        shared_ptr<Conn> GetConn(int fd);
        bool RemoveConn(int fd);

    //测试
    public:
        shared_ptr<BaseMsg> MakeMsg(uint32_t source, char *buff, int len);
};